package com.ruoyi.pms.service.imp;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.util.StringUtil;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.pms.domain.*;
import com.ruoyi.pms.domain.vo.TaskUserDetailVO;
import com.ruoyi.pms.domain.vo.TaskUserVO;
import com.ruoyi.pms.dto.calendar.ProjectCalendarInfoVm;
import com.ruoyi.pms.dto.calendar.WorkTimeListVm;
import com.ruoyi.pms.dto.resources.ProjectListResourcesVm;
import com.ruoyi.pms.dto.task.*;
import com.ruoyi.pms.mapper.*;
import com.ruoyi.pms.service.CalendarService;
import com.ruoyi.pms.service.DynamicsService;
import com.ruoyi.pms.service.TaskService;
import com.ruoyi.system.mapper.SysUserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@Service
public class TaskReportService {
    @Resource
    TaskMapper taskMapper;
    @Resource
    CustomerMapper customerMapper;
    @Resource
    SysUserMapper sysUserMapper;
    @Resource
    TaskAssmtMapper taskAssmtMapper;
    @Resource
    ProjectMapper projectMapper;

    public List<TaskUserVO> selectUserTasksPage(TaskUserVO query) {
        // 1、必须第一步先查询客户，因为有分页
        SysUser userQuery = new SysUser();
        userQuery.setDelFlag("0");
        userQuery.setStatus("0");
        List<SysUser> list = sysUserMapper.selectUserList(userQuery);
        Map<Long,SysUser> userMap = list.stream().collect(Collectors.toMap(SysUser::getUserId, u -> u));
        List<Long> userIds = new ArrayList<>();
        // 查询单个用户或全部用户
        if(StringUtil.isEmpty(query.getUserId())) {
            userIds = list.stream().map(SysUser::getUserId).collect(Collectors.toList());
        } else {
            userIds.add(Long.parseLong(query.getUserId()));
        }
        // 2、第二步查询时间区间内用户的任务
        QueryWrapper wrapper = new QueryWrapper<ProjectTask>();
        wrapper.in("assign_user_id", userIds);
        if(query.getStartDate() != null) {
            //大于开始时间
            wrapper.ge("start_date", query.getStartDate());
        }
        if(query.getEndDate() != null) {
            wrapper.le("end_date", query.getEndDate());
        }
        wrapper.orderByAsc("assign_user_id");
        List<ProjectTask> taskList = taskMapper.selectList(wrapper);
        if(taskList.size() == 0) {
            return new ArrayList<>();
        }
        // 查询任务考核记录
        List<String> taskIds = taskList.stream().map(ProjectTask::getId).collect(Collectors.toList());
        List<TaskAssmt> taskDeferList = taskAssmtMapper.selectList(new QueryWrapper<TaskAssmt>().in("task_id", taskIds));
        Map<String, TaskAssmt> assmtMap = taskDeferList.stream().collect(Collectors.toMap(TaskAssmt::getTaskId, taskAssmt -> taskAssmt));
        // 3、第三步 累加数据 封装数据
        Map<Long, TaskUserVO> taskUserMap = new HashMap<>();
        for(ProjectTask projectTask : taskList) {
            TaskUserVO taskUserVO = taskUserMap.get(projectTask.getAssignUserId());
            // map放第一个
            if(taskUserVO == null) {
                taskUserVO = new TaskUserVO("init");
                taskUserVO.setUserId(String.valueOf(projectTask.getAssignUserId()));
                taskUserVO.setStartDate(projectTask.getStartDate());
                taskUserVO.setEndDate(projectTask.getEndDate());
                taskUserMap.put(projectTask.getAssignUserId(), taskUserVO);
            }
            if(compareDates(taskUserVO.getStartDate(), projectTask.getStartDate()) > 0) {
                taskUserVO.setStartDate(projectTask.getStartDate());
            }
            if(compareDates(taskUserVO.getEndDate(), projectTask.getEndDate()) < 0) {
                taskUserVO.setEndDate(projectTask.getEndDate());
            }
            // 任务总数
            taskUserVO.setTaskCount(taskUserVO.getTaskCount() + 1);
            // 逾期未完成
            if(compareDates(projectTask.getEndDate(), new Date()) > 0 && projectTask.getProgress() < 100) {
                taskUserVO.setOverdue(taskUserVO.getOverdue() + 1);
            }
            // 进行中任务
            if(compareDates(projectTask.getEndDate(), new Date()) <= 0 && projectTask.getProgress() < 100) {
                taskUserVO.setDoing(taskUserVO.getDoing() + 1);
            }
            // 已完成任务
            if(projectTask.getProgress() == 100) {
                taskUserVO.setCompleted(taskUserVO.getCompleted() + 1);
                TaskAssmt taskAssmt = assmtMap.get(projectTask.getId());
                // 待考核任务
                if(taskAssmt == null) {
                    taskUserVO.setAwaitAssmt(taskUserVO.getAwaitAssmt() + 1);
                }
                // 已考核任务
                else {
                    taskUserVO.setAssmted(taskUserVO.getAssmted() + 1);
                    // 临时累加总分，最后计算平均分
                    taskUserVO.setScore(taskAssmt.getScore() + taskUserVO.getScore());
                }
            }
        }
        List<TaskUserVO> resultList = new ArrayList<>();
        for(TaskUserVO taskUserVO : taskUserMap.values()) {
            taskUserVO.setUserName(userMap.get(Long.parseLong(taskUserVO.getUserId())).getNickName());
            if(taskUserVO.getAssmted() > 0) {
                double avageScore = taskUserVO.getScore() / taskUserVO.getAssmted();
                taskUserVO.setScoreStr(String.format("%.2f", avageScore));
            } else {
                taskUserVO.setScoreStr("未考核");
            }
            resultList.add(taskUserVO);
        }
        return resultList;
    }

    public int compareDates(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();

        cal1.setTime(date1);
        cal2.setTime(date2);

        // 将时间设置为午夜，忽略时分秒
        setToStartOfDay(cal1);
        setToStartOfDay(cal2);

        return cal1.compareTo(cal2);
    }

    private static void setToStartOfDay(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
    }

    public List<TaskUserDetailVO> selectUserTasksDetailPage(TaskUserDetailVO taskUserVO) {
        List<TaskUserDetailVO> detailList = new ArrayList<>();
        // 查询任务考核记录
        List<TaskAssmt> taskDeferList = taskAssmtMapper.selectList(new QueryWrapper<>());
        List<String> assmtTaskIds = taskDeferList.stream().map(TaskAssmt::getTaskId).collect(Collectors.toList());
        if(assmtTaskIds.size() == 0) {
            assmtTaskIds.add("-1");
        }
        // 查询任务列表
        LambdaQueryWrapper<ProjectTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(!StringUtils.isEmpty(taskUserVO.getTaskName()), ProjectTask::getTaskName, taskUserVO.getTaskName());
        wrapper.eq(!StringUtils.isEmpty(taskUserVO.getAssignUserId()), ProjectTask::getAssignUserId, taskUserVO.getAssignUserId());
        if(taskUserVO.getStartDate() != null) {
            //大于开始时间
            wrapper.ge(ProjectTask::getStartDate, taskUserVO.getStartDate());
        }
        if(taskUserVO.getEndDate() != null) {
            wrapper.le(ProjectTask::getEndDate, taskUserVO.getEndDate());
        }
        // 已逾期
        if("overdue".equals(taskUserVO.getType())) {
            wrapper.gt(ProjectTask::getEndDate, new Date());
            wrapper.lt(ProjectTask::getProgress, 100);
        }
        // 进行中
        else if("doing".equals(taskUserVO.getType())) {
            wrapper.le(ProjectTask::getEndDate, new Date());
            wrapper.lt(ProjectTask::getProgress, 100);
        }
        // 已完成
        else if("completed".equals(taskUserVO.getType())) {
            wrapper.eq(ProjectTask::getProgress, 100);
        }
        // 待考核
        else if("awaitAssmt".equals(taskUserVO.getType())) {
            wrapper.eq(ProjectTask::getProgress, 100);
            wrapper.notIn(ProjectTask::getId, assmtTaskIds);
        }
        // 已考核
        else if("assmted".equals(taskUserVO.getType())) {
            wrapper.eq(ProjectTask::getProgress, 100);
            wrapper.in(ProjectTask::getId, assmtTaskIds);
        }
        List<ProjectTask> taskList = taskMapper.selectList(wrapper);

        // 转换数据
        if(taskList.size() == 0) {
            return detailList;
        } else {
            taskList.forEach(taks -> {
                TaskUserDetailVO detailVO = new TaskUserDetailVO();
                BeanUtils.copyProperties(taks, detailVO);
                detailList.add(detailVO);
            });
        }

        // 查询项目名称
        List<String> projectIds = taskList.stream().map(ProjectTask::getProjectId).collect(Collectors.toList());
        Map<String, Project> projectMap = projectMapper.selectList(new QueryWrapper<Project>().in("id", projectIds))
                .stream().collect(Collectors.toMap(Project::getId, project -> project));
        // 查询责任人名称
        List<Long> userIds = taskList.stream().map(ProjectTask::getAssignUserId).collect(Collectors.toList());
        Map<Long, SysUser> userMap = sysUserMapper.selectList(new QueryWrapper<SysUser>().in("user_id", userIds))
                .stream().collect(Collectors.toMap(SysUser::getUserId, user -> user));
        // 封装数据
        detailList.forEach(taskVO -> {
            taskVO.setProjectName(projectMap.get(taskVO.getProjectId()).getProjectName());
            taskVO.setAssignUserName(userMap.get(taskVO.getAssignUserId()).getNickName());
        });

        return detailList;
    }
}
